/* eslint-disable indent */
/*
 * @Author: your name
 * @Date: 2020-10-16 10:38:49
 * @LastEditTime: 2022-07-23 13:01:11
 * @LastEditors: 晟松
 * @Description: In User Settings Edit
 * @FilePath: \urban-manage-vued:\Code\vue\volunteer-vue3-admin\src\plugins\axios.js
 */
"use strict";

import axios from "axios";
import Qs from "qs";
import NProgress from "nprogress";

// Full config:  https://github.com/axios/axios#request-config
// axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

// const baseURL = process.env.baseURL || process.env.apiUrl || "https://volkoa.chengsong.info/api";
const baseURL = "http://localhost:4000/api";
// const baseURL = "/api";

let config = {
    Global: true,
    baseURL,
    // timeout: 60 * 1000, // Timeout
    // withCredentials: true, // Check cross-site Access-Control
    // {"userName":"Administrator","pwd":"123456"}
    // userName=Administrator&pwd=123456
};

// nginx代理转发失败似乎罪魁祸首就是这个东西
// if (VE_ENV.MODE === "production") {
//     config.transformRequest = [(data) => Qs.parse(data)];
// }

export const _axios = axios.create(config);

// export const request = {};

const install = (app, {router, store, opt}) => {
    let ve_loading;
    let ve_message = null;
    let loadingCount = 0;
    // 请求拦截
    _axios.interceptors.request.use(
        (config) => {
            // console.log("config: ", config);

            NProgress.done();
            if (config.Global) {
                NProgress.start();
                // 不知道这$loading哪挂载的？
                // https://element-plus.gitee.io/zh-CN/component/loading.html#%E4%BB%A5%E6%9C%8D%E5%8A%A1%E7%9A%84%E6%96%B9%E5%BC%8F%E6%9D%A5%E8%B0%83%E7%94%A8
                /* 如果完整引入了 Element Plus，那么 app.config.globalProperties 上会有一个全局方法$loading，
                 * 它的调用方式为：this.$loading(options)，同样会返回一个 Loading 实例
                 */
                ve_loading = app.config.globalProperties.$loading({
                    lock: true,
                    text: "Loading",
                    spinner: "el-icon-loading",
                    background: "rgba(0,0,0,0.1)",
                });
            }
            loadingCount++;
            //*请求头添加token
            const token = store.getters.token;
            token && (config.headers.Authorization = token);

            // Do something before request is sent
            return config;
        },
        (error) => {
            // Do something with request error
            return Promise.reject(error);
        }
    );

    // Add a response interceptor
    // 响应拦截
    _axios.interceptors.response.use(
        (response) => {
            // TODO 根据响应头更新token
            // store.dispatch("app/set_token", new Date().getTime());

            loadingCount--;
            if (loadingCount <= 0) {
                NProgress.done();
                ve_loading.close();
            }

            let type = "success";
            if (response.data.code != "200") {
                type = "error";
            }
            if (ve_message) {
                ve_message.close();
                ve_message = null;
            }
            // 同理，也是element-plus的组件
            ve_message = app.config.globalProperties.$message({
                type,
                message: response.data.msg,
            });
            // Do something with response data
            return response.data;
        },
        (error) => {
            loadingCount--;
            if (loadingCount <= 0) {
                NProgress.done();
                ve_loading.close();
            }
            if (error && error.response) {
                let message = "";
                switch (error.response.status) {
                    case 400:
                        message = "请求错误";
                        break;
                    case 401: {
                        message = "未授权，请登录";
                        router.replace({
                            name: "Login",
                        });
                        break;
                    }
                    case 403:
                        message = "没有权限，拒绝访问";
                        break;
                    case 404:
                        message = `请求地址出错`;
                        break;
                    case 408:
                        message = "请求超时";
                        break;
                    case 500:
                        message = "服务器内部错误";
                        break;
                    case 501:
                        message = "服务未实现";
                        break;
                    case 502:
                        message = "网关错误";
                        break;
                    case 503:
                        message = "服务不可用";
                        break;
                    case 504:
                        message = "网关超时";
                        break;
                    case 505:
                        message = "HTTP版本不受支持";
                        break;
                    default:
                        break;
                }
                if (ve_message) {
                    ve_message.close();
                    ve_message = null;
                }
                ve_message = app.config.globalProperties.$message({
                    message,
                    type: "error",
                });
            }
            // Do something with response error
            return Promise.reject(error);
        }
    );

    const method = {
        post: (url, p, config) => _axios.post(url, p, config),
        get: (url, p, config) => _axios.get(url, Object.assign(config, {params: p})),
        put: (url, p, config) => _axios.put(url, p, config),
        delete: (url, p, config) => _axios.delete(url, p, config),
    };

    // 读取api/modules目录下的api文件，并将其挂载到一个全局变量上，有点不太认可
    let api = {};
    const files = require.context("@/api/modules", false, /\.js$/);
    files.keys().forEach((key) => {
        const fileName = key.replace(/(\.\/|\.js)/g, "");
        api[fileName] = {};
        let obj = files(key);
        // console.log("obj: ", obj, Object.keys(obj));
        Object.keys(obj).forEach((item) => {
            api[fileName][item] = (p, config = {}) =>
                method[obj[item].type](obj[item].url, p, config);
        });
    });

    // 挂载到全局window上
    window[opt] = api;
    // console.log("api all in axios: ", api);

    // 下面的用法在之前(Vue 2.x)类似于此
    // Vue.prototype.$http = () => {};
    // 使用的话vue2的语法：this.$http
    // vue3需要导入一个方法获取实例：getCurrentInstance https://www.cnblogs.com/zzwlong/p/14987695.html
    app.config.globalProperties[opt] = api;
};

export default {install};
